package com.zackeus.common.utils;

import androidx.annotation.NonNull;

import java.io.File;

/**
 * @name: FileUtils
 * @author: zz
 * @date: 2022/9/6
 */
public class FileUtils {

    private FileUtils() {
        throw new UnsupportedOperationException("u can't instantiate me...");
    }

    /**
     * 创建指定的目录。 如果指定的目录的父目录不存在则创建其目录书上所有需要的父目录
     * @param fileName 要创建的目录的目录名
     * @return 完全创建成功时返回true，否则返回false。
     * @since 1.0
     */
    public static File makeDirectory(String fileName) {
        File file = new File(fileName);
        if (!file.exists()) {
            //noinspection ResultOfMethodCallIgnored
            file.mkdirs();
        }
        return file;
    }

    /**
     * 判断文件是否存在
     * @param file 文件
     * @return {@code true}: 存在<br>{@code false}: 不存在
     */
    public static boolean isFileExists(final File file) {
        if (file == null) {
            return Boolean.FALSE;
        }
        return file.exists();
    }

    /**
     * 判断文件是否存在
     * @param filePath 文件路径
     * @return {@code true}: 存在<br>{@code false}: 不存在
     */
    public static boolean isFileExists(final String filePath) {
        File file = new File(filePath);
        return file.exists();
    }

    /**
     * 获取全路径中的最长目录
     *
     * @param filePath 文件路径
     * @return filePath 最长目录
     */
    public static String getDirName(final String filePath) {
        if (StringUtils.isBlank(filePath)) {
            return filePath;
        }
        int lastSep = filePath.lastIndexOf(File.separator);
        return lastSep == -1 ? "" : filePath.substring(0, lastSep + 1);
    }

    /**
     * 获取应用的私有存储目录
     * <pre>path: /data/data/package/</pre>
     *
     * @return 此应用的缓存目录
     */
    public static String getAppIntPath() {
        File appIntCacheFile = Utils.getContext().getCacheDir();
        if (appIntCacheFile != null) {
            String appIntCachePath = appIntCacheFile.getAbsolutePath();
            return getDirName(appIntCachePath);
        }
        return null;
    }

    /**
     * 获取此应用在外置储存中的私有存储目录
     * <pre>path: /storage/emulated/0/Android/data/package/</pre>
     *
     * @return 此应用在外置储存中的缓存目录
     */
    public static String getAppExtPath() {
        File appExtCacheFile = Utils.getContext().getExternalCacheDir();
        if (appExtCacheFile != null) {
            String appExtCachePath = appExtCacheFile.getAbsolutePath();
            return getDirName(appExtCachePath);
        }
        return null;
    }

    /**
     * 是否是私有目录
     *
     *  <pre>path: /data/data/package/</pre>
     *  <pre>path: /storage/emulated/0/Android/data/package/</pre>
     * @param path 需要判断的目录
     * @return 是否是私有目录
     */
    public static boolean isPrivatePath(@NonNull String path) {
        if (StringUtils.isBlank(path)) {
            return Boolean.FALSE;
        }
        String appIntPath = getAppIntPath();
        String appExtPath = getAppExtPath();
        return (StringUtils.isNotBlank(appIntPath) && path.startsWith(appIntPath))
                || (StringUtils.isNotBlank(appExtPath) && path.startsWith(appExtPath));
    }

    /**
     * 删除文件，可以是文件或文件夹
     * @param fileName
     * @return
     */
    public static boolean delete(String fileName) {
        return delete(new File(fileName));

    }

    /**
     * 删除文件，可以是文件或文件夹
     * @param file
     * @return
     */
    public static boolean delete(File file) {
        if (!file.exists()) {
            return Boolean.TRUE;
        } else {
            if (file.isFile())
                return deleteFile(file);
            else
                return deleteDirectory(file);
        }
    }

    /**
     * 删除单个文件
     * @param fileName
     * @return
     */
    public static boolean deleteFile(String fileName) {
        return deleteFile(new File(fileName));
    }

    /**
     * 删除单个文件
     * @param file
     * @return
     */
    public static boolean deleteFile(File file) {
        /* 如果文件路径所对应的文件存在，并且是一个文件，则直接删除 */
        if (file.exists() && file.isFile()) {
            return file.delete();
        }
        /* 不存在 */
        return Boolean.TRUE;
    }

    /**
     * 删除目录及目录下的文件
     * @param dir
     * @return
     */
    public static boolean deleteDirectory(String dir) {
        /* 如果dir不以文件分隔符结尾，自动添加文件分隔符 */
        if (!dir.endsWith(File.separator))
            dir = dir + File.separator;
        return deleteDirectory(new File(dir));
    }

    /**
     * 删除目录及目录下的文件
     * @param dirFile
     * @return
     */
    public static boolean deleteDirectory(File dirFile) {
        /* 如果dir对应的文件不存在，或者不是一个目录，则忽略 */
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
            return Boolean.TRUE;
        }

        /* 删除文件夹中的所有文件包括子目录 */
        File[] files = dirFile.listFiles();
        if (files == null)
            return Boolean.FALSE;

        boolean flag = Boolean.TRUE;
        for (File file : files) {
            // 删除子文件
            if (file.isFile()) {
                flag = FileUtils.deleteFile(file);
                if (!flag)
                    break;
            }
            // 删除子目录
            else if (file.isDirectory()) {
                flag = FileUtils.deleteDirectory(file);
                if (!flag)
                    break;
            }
        }
        if (!flag) {
            return Boolean.FALSE;
        }
        /* 删除当前目录 */
        return dirFile.delete();
    }

}
